# -*- encoding: utf-8 -*-
import time, datetime
from collections import defaultdict, OrderedDict
from operator import itemgetter
from itertools import groupby
import math
from odoo import models, fields, api, _, tools, SUPERUSER_ID

from odoo.tools import float_compare, float_round, float_is_zero
from odoo.exceptions import UserError, ValidationError
from odoo.addons import base_cw


class generate_cost_voucher_wizard(models.TransientModel):
    _name = 'generate.cost.voucher.wizard'
    _description = u'生成成本凭证向导'

    period_id = fields.Many2one('account.period', u'期别', domain="[('gl_state','=','open')]")


    def action_confirm(self):
        self.ensure_one()
        voucher = self.env['account.voucher']
        voucher_category_id = self.env.ref('cncw_ledger.account_voucher_category_09')
        self.generate_account_voucher_cost_1(voucher, voucher_category_id)
        self.generate_account_voucher_cost_2(voucher, voucher_category_id)
        self.generate_account_voucher_cost_3(voucher, voucher_category_id)

    @api.model
    def generate_account_voucher_cost_1(self, voucher, voucher_category_id):
        cost_template = self.env.ref('cncw_ledger.account_voucher_template_cost_1')
        name = "FG{period_name}_{code}".format(period_name=self.period_id.name,
                                               code=cost_template.code)
        domain = [('name', '=', name)]
        cost_master_id = voucher.search(domain, limit=1)
        if cost_master_id:
            if cost_master_id.state == 'draft':
                cost_master_id.unlink()
            else:
                raise UserError(u"本期成本凭证已产生且已审核!,不可重复产生.如要重新产生，请选取消审核!")
        value = dict(name=name,
                     date=self.period_id.date_stop,
                     note=cost_template.name,
                     voucher_category_id=voucher_category_id.id, )
        cost_master_id = voucher.create(value)
        items = []
        cost_1_amount2 = self.get_cost_1_amount2()
        cost_1_amount3 = self.get_cost_1_amount3()
        cost_1_amount4 = self.get_cost_1_amount4()
        cost_1_amount5 = self.get_cost_1_amount5()
        cost_1_amount6 = self.get_cost_1_amount6()
        cost_1_amount7 = self.get_cost_1_amount7()
        cost_1_amount1 = cost_1_amount2 + cost_1_amount3 + cost_1_amount4 + cost_1_amount5 + cost_1_amount6 + cost_1_amount7
        for line in sorted(cost_template.line_ids, key=lambda x: x.sequence):
            self.get_voucher_line(cost_1_amount1, items, line, note='存货--在制品')
            self.get_voucher_line(cost_1_amount2, items, line, note='存货--原材料')
            self.get_voucher_line(cost_1_amount3, items, line, note='存货--半成品')
            self.get_voucher_line(cost_1_amount4, items, line, note='存货--产成品')
            self.get_voucher_line(cost_1_amount5, items, line, note='存货--直接人工')
            self.get_voucher_line(cost_1_amount6, items, line, note='存货--制造费用')
            self.get_voucher_line(cost_1_amount7, items, line, note='存货--外协加工费')
        if items:
            cost_master_id.write(dict(line_ids=items))

    @api.model
    def generate_account_voucher_cost_2(self, voucher, voucher_category_id):
        cost_template = self.env.ref('cncw_ledger.account_voucher_template_cost_2')
        name = "FG{period_name}_{code}".format(period_name=self.period_id.name,
                                               code=cost_template.code)
        domain = [('name', '=', name)]
        cost_master_id = voucher.search(domain, limit=1)
        if cost_master_id:
            if cost_master_id.state == 'draft':
                cost_master_id.unlink()
            else:
                raise UserError(u"本期成本凭证已产生且已审核!,不可重复产生.如要重新产生，请选取消审核!")
        value = dict(name=name,
                     date=self.period_id.date_stop,
                     note=cost_template.name,
                     voucher_category_id=voucher_category_id.id, )
        cost_master_id = voucher.create(value)
        items = []
        cost_2_amount1 = self.get_cost_2_amount1()
        cost_2_amount2 = self.get_cost_2_amount2()
        cost_2_amount3 = cost_2_amount1 + cost_2_amount2
        for line in sorted(cost_template.line_ids, key=lambda x: x.sequence):
            self.get_voucher_line(cost_2_amount1, items, line, note='存货--半成品')
            self.get_voucher_line(cost_2_amount2, items, line, note='存货--产成品')
            self.get_voucher_line(cost_2_amount3, items, line, note='存货--在制品')
        if items:
            cost_master_id.write(dict(line_ids=items))

    @api.model
    def generate_account_voucher_cost_3(self, voucher, voucher_category_id):
        cost_template = self.env.ref('cncw_ledger.account_voucher_template_cost_3')
        name = "FG{period_name}_{code}".format(period_name=self.period_id.name,
                                               code=cost_template.code)
        domain = [('name', '=', name)]
        cost_master_id = voucher.search(domain, limit=1)
        if cost_master_id:
            if cost_master_id.state == 'draft':
                cost_master_id.action_cancel()
                cost_master_id.unlink()
            else:
                raise UserError(u"本期成本凭证已产生且已审核!,不可重复产生.如要重新产生，请选取消审核!")
        value = dict(name=name,
                     date=self.period_id.date_stop,
                     note=cost_template.name,
                     voucher_category_id=voucher_category_id.id, )
        cost_master_id = voucher.create(value)
        items = []
        cost_3_amount2 = self.get_cost_3_amount2()
        cost_3_amount3 = self.get_cost_3_amount3()
        cost_3_amount4 = self.get_cost_3_amount4()
        cost_3_amount5 = self.get_cost_3_amount5()
        cost_3_amount1 = cost_3_amount2 + cost_3_amount3 + cost_3_amount4 + cost_3_amount5
        for line in sorted(cost_template.line_ids, key=lambda x: x.sequence):
            self.get_voucher_line(cost_3_amount1, items, line, note='销售成本')
            self.get_voucher_line(cost_3_amount2, items, line, note='销售成本(销售退回)')
            self.get_voucher_line(cost_3_amount3, items, line, note='存货--原材料')
            self.get_voucher_line(cost_3_amount4, items, line, note='存货--半成品')
            self.get_voucher_line(cost_3_amount5, items, line, note='存货--产成品')

        if items:
            cost_master_id.write(dict(line_ids=items))

    @api.model
    def get_voucher_line(self, amount, items, line, note):
        # if line.account_id and line.note == note:
        if line.note == note:
            item = dict(sequence=line.sequence,
                        dc_type=line.dc_type,
                        account_id=line.account_id.id,
                        debit=amount if line.dc_type == 'D' else 0,
                        lc_debit=amount if line.dc_type == 'D' else 0,
                        credit=amount if line.dc_type == 'C' else 0,
                        lc_credit=amount if line.dc_type == 'C' else 0,
                        name=line.note)
            items.append((0, 0, item))

    @api.model
    def get_cost_1_amount2(self):
        amount = 0
        domain = [('date', '>=', self.period_id.date_start),
                  ('date', '<=', self.period_id.date_stop),
                  ('state', '=', 'done'),
                  ('product_id.product_type', '=', 'A'),
                  ('raw_material_production_id', '!=', False),
                  ]
        objs = self.env['stock.move'].search(domain)
        if objs:
            amount = sum(objs.mapped('total_cost'))
        return amount

    @api.model
    def get_cost_1_amount3(self):
        amount = 0
        domain = [('date', '>=', self.period_id.date_start),
                  ('date', '<=', self.period_id.date_stop),
                  ('state', '=', 'done'),
                  ('product_id.product_type', '=', 'B'),
                  ('raw_material_production_id', '!=', False),
                  ]
        objs = self.env['stock.move'].search(domain)
        if objs:
            amount = sum(objs.mapped('total_cost'))
        return amount

    @api.model
    def get_cost_1_amount4(self):
        amount = 0
        domain = [('date', '>=', self.period_id.date_start),
                  ('date', '<=', self.period_id.date_stop),
                  ('state', '=', 'done'),
                  ('product_id.product_type', '=', 'C'),
                  ('raw_material_production_id', '!=', False),
                  ]
        objs = self.env['stock.move'].search(domain)
        if objs:
            amount = sum(objs.mapped('total_cost'))
        return amount

    @api.model
    def get_cost_1_amount5(self):
        amount = 0
        domain = [('period_id', '=', self.period_id.id)]
        objs = self.env['workcenter.expense'].search(domain)
        if objs:
            amount = sum(objs.mapped('labor'))
        return amount

    @api.model
    def get_cost_1_amount6(self):
        amount = 0
        domain = [('period_id', '=', self.period_id.id)]
        objs = self.env['workcenter.expense'].search(domain)
        if objs:
            amount = sum(objs.mapped('overhead'))
        return amount

    @api.model
    def get_cost_1_amount7(self):
        amount = 0
        domain = [('period_id', '=', self.period_id.id)]
        objs = self.env['workcenter.expense'].search(domain)
        if objs:
            amount = sum(objs.mapped('subcontract'))
        return amount

    @api.model
    def get_cost_2_amount1(self):
        amount = 0
        domain = [('date', '>=', self.period_id.date_start),
                  ('date', '<=', self.period_id.date_stop),
                  ('state', '=', 'done'),
                  ('product_id.product_type', '=', 'B'),
                  ('production_id', '!=', False),
                  ]
        objs = self.env['stock.move'].search(domain)
        if objs:
            amount = sum(objs.mapped('total_cost'))
        return amount

    @api.model
    def get_cost_2_amount2(self):
        amount = 0
        domain = [('date', '>=', self.period_id.date_start),
                  ('date', '<=', self.period_id.date_stop),
                  ('state', '=', 'done'),
                  ('product_id.product_type', '=', 'C'),
                  ('production_id', '!=', False),
                  ]
        objs = self.env['stock.move'].search(domain)
        if objs:
            amount = sum(objs.mapped('total_cost'))
        return amount

    @api.model
    def get_cost_3_amount2(self):
        amount = 0
        domain = [('date', '>=', self.period_id.date_start),
                  ('date', '<=', self.period_id.date_stop),
                  ('state', '=', 'done'),
                  ('picking_type_id.table_name', '=', 'sale_return_storage'),
                  ]
        objs = self.env['stock.move'].search(domain)
        if objs:
            amount = sum(objs.mapped('total_cost'))
        return amount

    @api.model
    def get_cost_3_amount3(self):
        amount = 0
        domain = [('date', '>=', self.period_id.date_start),
                  ('date', '<=', self.period_id.date_stop),
                  ('state', '=', 'done'),
                  ('product_id.product_type', '=', 'A'),
                  ('picking_type_id.table_name', '=', 'stock_delivery'),
                  ]
        objs = self.env['stock.move'].search(domain)
        if objs:
            amount = sum(objs.mapped('total_cost'))
        return amount

    @api.model
    def get_cost_3_amount4(self):
        amount = 0
        domain = [('date', '>=', self.period_id.date_start),
                  ('date', '<=', self.period_id.date_stop),
                  ('state', '=', 'done'),
                  ('product_id.product_type', '=', 'B'),
                  ('picking_type_id.table_name', '=', 'stock_delivery'),
                  ]
        objs = self.env['stock.move'].search(domain)
        if objs:
            amount = sum(objs.mapped('total_cost'))
        return amount

    @api.model
    def get_cost_3_amount5(self):
        amount = 0
        domain = [('date', '>=', self.period_id.date_start),
                  ('date', '<=', self.period_id.date_stop),
                  ('state', '=', 'done'),
                  ('product_id.product_type', '=', 'C'),
                  ('picking_type_id.table_name', '=', 'stock_delivery'),
                  ]
        objs = self.env['stock.move'].search(domain)
        if objs:
            amount = sum(objs.mapped('total_cost'))
        return amount
